package com.xpec.c4.service.module.datacenter.player;

import java.math.BigDecimal;
import java.util.ArrayList;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.ms.game.common.container.BasicSetting;
import com.ms.game.invitefriend.InviteCodeProcessor;
import com.ms.game.invitefriend.bin.InviteCodeInfo;
import com.ms.game.invitefriend.bin.InviteCodeRewardBinUtil;
import com.ms.game.invitefriend.bin.InviteCodeType;
import com.ms.game.invitefriend.bin.ItemInfo;
import com.ms.game.invitefriend.db.DistributorInviteCodeDAO;
import com.ms.game.invitefriend.db.DistributorInviteCodesModel;
import com.ms.game.invitefriend.db.InviteCodeGroupModel;
import com.ms.game.invitefriend.db.InviteCodeModel;
import com.ms.game.invitefriend.db.InviteFriendDAO;
import com.ms.game.itembox.ItemChangeWay;
import com.ms.game.itembox.db.ItemDAO;
import com.ms.game.itembox.db.PlayerItemChangeLogModel;
import com.ms.game.itembox.db.PlayerItemModel;
import com.ms.player.Player;
import com.ms.player.PlayerIdentityType;
import com.ms.service.error.ErrorCode;
import com.ms.service.module.account.Account;
import com.ms.service.module.account.db.AccountDAO;
import com.ms.service.module.analysisgroup.AnalysisGroupProcessor;
import com.ms.service.module.analysisgroup.CoinExpenditureWay;
import com.mysql.jdbc.MysqlErrorNumbers;
import com.xpec.c4.db.dao.PlayerDAO;
import com.xpec.c4.game.datamanager.ResultNo;
import com.xpec.c4.game.datamanager.agent.PlayerData;
import com.xpec.c4.game.utility.GUIDFactory;
import com.xpec.c4.game.utility.GUIDType;
import com.xpec.c4.game.utility.GameUtility;


public class CreatePlayerDataAsync extends LoadPlayerDataAsync{

	/**
	 * 
	 */
	private static final Log log = LogFactory.getLog(CreatePlayerDataAsync.class);

	/**
	 * 邀請碼處理器
	 */
	private InviteCodeProcessor inviteCodeProc = new InviteCodeProcessor();

	private static final String LEVLE_BOX_LV1 = "TREASURE_BOX_LEVEL_LV1"; 
	
	@Override
	public void asyncExecute() {

		PlayerData dataInfo = (PlayerData) getDataInfo();
		
		if(dataInfo != null && dataInfo.getData() != null){
			
			Player player = (Player) dataInfo.getData();
			
			InviteCodeType codeType = null;
			//邀請碼
			InviteCodeModel inviteCodeModel = null;
			//群組邀請碼
			InviteCodeGroupModel inviteCodeGroupModel = null;
			//經銷商邀請碼
			DistributorInviteCodesModel distributorInviteCodesModel = null;
			Account account = null;
			
			String inviteCode = player.getUplineCode();
			
			// 創角時有填寫邀請碼
			if (GameUtility.isHaveString(inviteCode)) {
				// 載入 account data
				account = AccountDAO.loadAccountByAccountId(player.getAccountId());
				if (account == null) {
					resultCode = ResultNo.DATA_NOT_FOUND;
					if (log.isErrorEnabled()) {
						log.error("load account (" + player.getAccountId() + ") fail when create player (" + player + ") data.");
					}
					return;
				}
				
				if(log.isInfoEnabled()) {
					log.info("CreatePlayerDataAsync => Account : " + account.getAccountId() + " | use : " + inviteCode);
				}

				// 非認證帳號
				if (!account.isVerifiedMember()) {
					//20171129這邊因應認證設定調整，理應更改errorCode的意義為"未認證帳號無法使用"
					resultCode = ErrorCode.ACCOUNT_INVITE_CODE_MUST_HAVE_BIND_PHONE_NUMBER;	
					return;
				}
						
				if (player.getUplineCode().indexOf(InviteCodeProcessor.DISTRIBUTOR_INVITE_CODE_IDENTIFY) == -1) {
					//一般邀請碼
					inviteCodeModel =  InviteFriendDAO.getInviteCodeModel(inviteCode);
					if (inviteCodeModel == null) {
						//邀請碼不存在
						resultCode = ErrorCode.ACCOUNT_INVITE_CODE_CANT_GET_CODE_TYPE;
						return;
					}
					
					//邀請碼的類型
					codeType = inviteCodeModel.getType();
					
					if(codeType == InviteCodeType.ACTIVITY_SHARE_INVITE_CODE) {
						inviteCodeGroupModel = InviteFriendDAO.getInviteCodeGroupModelById(inviteCodeModel.getGroupId());
						if(inviteCodeGroupModel == null) {
							resultCode = ErrorCode.ACCOUNT_INVITE_CODE_CANT_GET_CODE_TYPE;
							return;
						}
					}
					
				}else {
					//經銷商邀請碼
					distributorInviteCodesModel = DistributorInviteCodeDAO.getDistributorInviteCodesModel(inviteCode);
					if (distributorInviteCodesModel == null) {
						resultCode = ErrorCode.ACCOUNT_INVITE_CODE_CANT_GET_CODE_TYPE;
						return;
					}
					
//					if(!DistributorInviteCodeDAO.isDistributorInviteCodeShowing(distributorInviteCodesModel)){
//						resultCode = ErrorCode.ACCOUNT_INVITE_CODE_CANT_GET_CODE_TYPE;
//						return;
//					}
					
					// 直接設定成經銷商邀請碼
					codeType = InviteCodeType.DISTRIBUTOR_INVITE_CODE;
				}

				InviteCodeInfo info = InviteCodeRewardBinUtil.getInviteCodeInfo(codeType);

				// 邀請碼的相關檢查
				resultCode = inviteCodeProc.checkPlayerData(codeType, player, inviteCodeModel, distributorInviteCodesModel, info, account);
				if (resultCode != ErrorCode.SUCCESS) {
					return;
				}
				
				//把用過的mark成true
				boolean markResult = false;
				if (codeType == InviteCodeType.DISTRIBUTOR_INVITE_CODE) {
					//經銷商邀請碼走這
					markResult = DistributorInviteCodeDAO.updateUsedDistributorInviteCode(player, distributorInviteCodesModel.getInviteCode());
					if (!markResult) {
						//如果這個都沒辦法做好就直接 return
						resultCode = ErrorCode.DB_OPERATION_FAIL;
						return;
					}
					

					if (player.getPlayerIdentityType() == PlayerIdentityType.SUB_DISTRIBUTOR) {
						// 如果是子經銷商，要加到 SubDistributorsModel
						markResult = DistributorInviteCodeDAO.setSubDistributor(player);
					}
				} else {
					//一般邀請碼
					markResult = InviteFriendDAO.markUsedInviteCode(codeType, player.getUplineCode());
				}

				if (!markResult) {
					resultCode = ErrorCode.DB_OPERATION_FAIL;
					return;
				}

				// 將邀請碼的獎勵內容套到角色身上
				resultCode = inviteCodeProc.applyReward(codeType, player, inviteCodeGroupModel, info);
				if (resultCode != ErrorCode.SUCCESS) {
					return;
				}
			}else{
				player.setTrialCoin(new BigDecimal(BasicSetting.getInstance().getDefaultTrialCoin()));
			}

			int[] errorCode = {0};
			boolean flag = PlayerDAO.savePlayer(player, errorCode);
		
			if(!flag){
				log.error("cannot save player:" + this.getDataInfo().getKey() );
				if (errorCode[0] == MysqlErrorNumbers.ER_DUP_KEY
						|| errorCode[0] == MysqlErrorNumbers.ER_DUP_KEYNAME
						|| errorCode[0] == MysqlErrorNumbers.ER_DUP_ENTRY
						|| errorCode[0] == MysqlErrorNumbers.ER_DUP_ENTRY_WITH_KEY_NAME)
					resultCode = ResultNo.DATA_DUPLICATE;
				else
					resultCode = ResultNo.DB_OPERATION_FAILED;
			}else{
				// player 寫入成功

				// 創角時有填寫邀請碼
				if (GameUtility.isHaveString(player.getUplineCode())) {
					// 寫入獲得邀請碼獎勵的 log
					inviteCodeProc.saveLog(getCurrentModuleServer());
					
					String items = null;
					//掃看看道具
					if(inviteCodeProc.getItemLogModelList().size() > 0){
						ArrayList<ItemInfo> itemList = new ArrayList<ItemInfo>();
						for (PlayerItemChangeLogModel model : inviteCodeProc.getItemLogModelList()) {
							ItemInfo item = new ItemInfo();
							item.setItemId(model.getItemId());
							item.setCount((int) model.getChangeCount());
							itemList.add(item);
						}
						
						items = inviteCodeProc.getGson().toJson(itemList);
					}
					//邀請碼使用紀錄
					if (!InviteFriendDAO.createInviteCodeUseRecord(player, inviteCodeModel, distributorInviteCodesModel ,account.getCooperatorAccountId(), player.getGoldCoin().longValue(), items)) {
						resultCode = ErrorCode.DB_OPERATION_FAIL;
						return;
					}
					
					//送到統計群統計C幣支出(產出)
					if(codeType.equals(InviteCodeType.ACTIVITY_INVITE_CODE) || codeType.equals(InviteCodeType.ACTIVITY_SHARE_INVITE_CODE)){
						AnalysisGroupProcessor.sendCoinExpenditureToAnalysis(CoinExpenditureWay.ACTIVITY_SHARE_CODE, player.getGoldCoin());
					}
					else if (codeType.equals(InviteCodeType.DISTRIBUTOR_INVITE_CODE)){
						AnalysisGroupProcessor.sendCoinExpenditureToAnalysis(CoinExpenditureWay.DISTRIBUTOR_INVITE_CODE, player.getGoldCoin());
					}
					else if (codeType.equals(InviteCodeType.NEW_INVITE_CODE)){
						AnalysisGroupProcessor.sendCoinExpenditureToAnalysis(CoinExpenditureWay.INVITE_CODE, player.getGoldCoin());
					}
				}
				
				if (player.isPlayer()) { //玩家才給一等升級寶箱
					PlayerItemModel playerItemModel = ItemDAO.createItemModel(ItemChangeWay.ADD_CREATE_PLAYER, player.getGuid().toString(), LEVLE_BOX_LV1, 1, 0, player.getLevel(), 0, "", "");
					ItemDAO.saveGameModel(playerItemModel);
					String orderId = GUIDFactory.createUUID(GUIDType.TYPE_ITEM).toString();
					PlayerItemChangeLogModel playerItemChangeLogModel = ItemDAO.createPlayerItemChangeLogModel(orderId, ItemChangeWay.ADD_CREATE_PLAYER, playerItemModel.getSn(), player, playerItemModel.getItemId(), 1, 0, 1, getSrcModuleID(), getSrcModuleID(), playerItemModel.getRefineLevel(), null);
					ItemDAO.saveLogModel(playerItemChangeLogModel);
				}
				
				resultCode = ResultNo.OK;
			}
		}else{
			resultCode = ResultNo.DATA_NOT_FOUND;
		}
	}

	@Override
	public void execute() {
		// callback
		if(dataManager != null){
			dataManager.createDataCallback(resultCode, dataInfo, srcModuleID,
					(dataInfo != null) ? dataInfo.getData() : null);
		}		
	}
}
